/*
* Copyright 2010 Competentum group
*
* Licensed under the GNU General Public License, Version 3.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.gnu.org/licenses/gpl.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.competentum.engines
{
	import com.competentum.builders.BindsBuilder;
	import com.competentum.builders.DataBuildersFactory;
	import com.competentum.builders.ProjectsBuilder;
	import com.competentum.controls.ADG;
	import com.competentum.events.EventReasons;
	import com.competentum.events.GroupingEvent;
	import com.competentum.events.ItemMoveEvent;
	import com.competentum.events.WorkloadEvent;
	import com.competentum.history.HistoryChangesManager;
	import com.competentum.vos.BindVO;
	import com.competentum.vos.ProjectVO;
	import com.competentum.windows.ScopesManager;
	import com.competentum.lib.data.builders.AbstractDataBuilder;
	import com.competentum.lib.data.vo.UniqueVO;
	import com.competentum.lib.engines.AbstractEngine;
	import com.competentum.lib.events.CommandEvent;
	
	/**
	 * Works with projects: adds, removes, updates them
	 * 
	 * @author Valentine Abanosimov
	 * */
	public class ProjectsEngine extends EngineWithView
	{
		public static const TYPE:String = "ProjectsEngine";
		
		private var _builder:ProjectsBuilder;
		private var _bindsBuilder:BindsBuilder;
		
		public function ProjectsEngine()
		{
			super(TYPE);
			addHandableCommand(EventReasons.INVALIDATE_RENDERERS);
		}
		
		override protected function activate(event:CommandEvent = null):void
		{
			super.activate(event);
			
			var wEvent:WorkloadEvent = event as WorkloadEvent;
			var redoEvent:WorkloadEvent;
			var hwEvent:WorkloadEvent;
			var item:ProjectVO;
			if (wEvent)
			{
				_builder = DataBuildersFactory.getDataBuilder(ProjectsBuilder.TYPE, wEvent.scope) as ProjectsBuilder;
				_bindsBuilder = DataBuildersFactory.getDataBuilder(BindsBuilder.TYPE, wEvent.scope) as BindsBuilder;
				if (wEvent.commandType == EventReasons.INVALIDATE_RENDERERS)
				{
					getView(wEvent.scope).invalidateRenderers();
				}
				if (wEvent.reason == EventReasons.REFRESH)
				{
					getView(wEvent.scope).refresh();
				}
				if (wEvent.reason == EventReasons.ADD)
				{
					if (wEvent.undoAllowed)
					{
						// if this is a user command
						// add undo action to history
						item =  _builder.createItem('noName', wEvent.valueItem.name, wEvent.valueItem.hours) as ProjectVO;
						if (wEvent is GroupingEvent)
						{
							(getView(wEvent.scope) as ADG).expandItem((wEvent as GroupingEvent).groupingItem, true);
						}
						hwEvent = new WorkloadEvent(CommandEvent.ACTIVATE_ENGINE);
						hwEvent.commandType = TYPE;
						hwEvent.item = item;
						hwEvent.reason = EventReasons.REMOVE;
						hwEvent.undoAllowed = false;
						redoEvent = new WorkloadEvent(CommandEvent.ACTIVATE_ENGINE);
						redoEvent.commandType = TYPE;
						redoEvent.item = item;
						redoEvent.reason = EventReasons.ADD;
						ScopesManager.currentScope.historyManager.addCommands([hwEvent], [redoEvent]);
					}
					else
					{
						_builder.addItem(wEvent.item);
					}
				}
				if (wEvent.reason == EventReasons.REMOVE)
				{
					var binds:Vector.<BindVO> = _bindsBuilder.getBindingsListForItem(wEvent.item);
					for (var i:int = 0; i < binds.length; i ++ )
					{
						_bindsBuilder.removeItem(binds[i]);
					}
					_builder.removeItem(wEvent.item);
					if (wEvent.undoAllowed)
					{
						// if this is a user command
						// add undo action to history
						// this undo action is complex. We need to create project and then add binds
						var events:Array = [];
						
						hwEvent = new WorkloadEvent(CommandEvent.ACTIVATE_ENGINE);
						hwEvent.commandType = TYPE;
						hwEvent.item = wEvent.item;
						hwEvent.reason = EventReasons.ADD;
						hwEvent.undoAllowed = false;
						events.push(hwEvent);
						
						for (var j:int = 0; j < binds.length; j ++ )
						{
							hwEvent = new WorkloadEvent(CommandEvent.ACTIVATE_ENGINE);
							hwEvent.commandType = BindsEngine.TYPE;
							hwEvent.item = binds[j];
							hwEvent.reason = EventReasons.ADD;
							hwEvent.undoAllowed = false;
							events.push(hwEvent);
						}
						
						redoEvent = new WorkloadEvent(CommandEvent.ACTIVATE_ENGINE);
						redoEvent.commandType = TYPE;
						redoEvent.item = wEvent.item;
						redoEvent.reason = EventReasons.REMOVE;
						ScopesManager.currentScope.historyManager.addCommands(events, [redoEvent]);
					}
				}
				if (wEvent.reason == EventReasons.UPDATE)
				{
					item = wEvent.item as ProjectVO;
					
					if (wEvent.undoAllowed)
					{
						// if this is a user command
						// prepare to add undo action to history
						hwEvent = new WorkloadEvent(CommandEvent.ACTIVATE_ENGINE);
						hwEvent.commandType = TYPE;
						hwEvent.item = item;
						var project:ProjectVO = _builder.createItem(item.name, item.groupingAttribute, item.hours, item.comments, null, false);
						hwEvent.valueItem = project;
						hwEvent.reason = EventReasons.UPDATE;
						hwEvent.undoAllowed = false;
					}
					
					var valueItem:ProjectVO = wEvent.valueItem as ProjectVO;
					item.name = valueItem.name;
					item.groupingAttribute = valueItem.groupingAttribute;
					item.hours = valueItem.hours;
					item.comments = valueItem.comments;
					item.notifyHolders();
					var bindList:Vector.<BindVO> = _bindsBuilder.getBindingsListForItem(item);
					for (var bindIndex:int = 0; bindIndex < bindList.length; bindIndex ++ )
					{
						var bind:BindVO = bindList[bindIndex] as BindVO;
						bind.employee.notifyHolders();
					}
					
					if (wEvent.undoAllowed)
					{
						// if this is a user command
						// add undo action to history
						redoEvent = new WorkloadEvent(CommandEvent.ACTIVATE_ENGINE);
						redoEvent.commandType = TYPE;
						redoEvent.item = wEvent.item;
						redoEvent.valueItem = wEvent.valueItem;
						redoEvent.reason = EventReasons.UPDATE;
						ScopesManager.currentScope.historyManager.addCommands([hwEvent], [redoEvent]);
					}
				}
				
				if (wEvent.reason == EventReasons.MOVE)
				{
					var imEvent:ItemMoveEvent = new ItemMoveEvent(CommandEvent.ACTIVATE_ENGINE);
					if (wEvent.undoAllowed)
					{
						// if this is a user command
						// prepare to add undo action to history
						imEvent.commandType = TYPE;
						imEvent.item = wEvent.item;
						imEvent.group = (wEvent.item as ProjectVO).groupingAttribute;
						imEvent.reason = EventReasons.MOVE;
						imEvent.undoAllowed = false;
					}
					(wEvent.item as ProjectVO).groupingAttribute = (wEvent as ItemMoveEvent).group;
					if (wEvent.undoAllowed)
					{
						// if this is a user command
						// add undo action to history
						redoEvent = new ItemMoveEvent(CommandEvent.ACTIVATE_ENGINE);
						redoEvent.commandType = TYPE;
						redoEvent.item = wEvent.item;
						redoEvent.reason = EventReasons.MOVE;
						(redoEvent as ItemMoveEvent).group = (wEvent as ItemMoveEvent).group;
						ScopesManager.currentScope.historyManager.addCommands([imEvent], [redoEvent]);
					}
					if (!wEvent.undoAllowed)
					{
						// if event from history, we need to refresh view
						getView(wEvent.scope).refresh();
					}
				}
			}
		}
	}
}